﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IFServerDLL.Model;
using System.ComponentModel;
using IFServerDLL;
using IFClientDLL.Model;

namespace IFClientDLL
{

    public class ClientBase : IClient
    {
        private ITryIF _tryif;
        private string _serverAddress;
        public ClientBase(ITryIF tryif,BackgroundWorker bw, string serverAddress, string rspAddress,string username,  string instrument)
        {
            _tryif = tryif;
            _serverAddress = serverAddress;
            SubscribeResponeClient proxyRsp = new SubscribeResponeClient();
            proxyRsp.StartByDebug(tryif.UserID, new Rsp(tryif,bw), rspAddress);
            PublishProxy proxy = new PublishProxy(serverAddress);
            tryif.DataServer.OnReceiveDBData += new Action<IFServerDLL.DB.MyDBData>(Tryif_OnReceiveData);
            try
            {
                var user = proxy.Login(new IFServerDLL.Broker.BrokerUserBase() { UserID = proxyRsp.ClientID, MarketInstrument = new List<string>() { instrument }, UserName = username });
                _Account = new AccountDemo(user.Account);
                _OrderHistory = new List<OrderBase>();
                _OrderOnhand = new List<OrderBase>();
                foreach (var x in user.OrderHistory)
                {
                    _OrderHistory.Add(x);
                    if (x.OrderStatusType == EnumOrderStatusType.撤单 || x.OrderStatusType == EnumOrderStatusType.未成交还在队列中 || x.OrderStatusType == EnumOrderStatusType.部分成交还在队列中)
                    {
                        _OrderOnhand.Add(x);
                    }
                }

                _TradeGroup = new List<TradeGroupBase>();
                _TradeHistory = new List<TradeBase>();
                _TradeOnHand = new List<TradeOnHand>();
                foreach (var x in user.TradeHistory)
                {
                    AddTrade(x);
                }
                
                _Account.UpdateAll(this);
            }
            catch (Exception ex)
            {
                _tryif.AddMessage(new MessageBase(ex.Message));
            }
        }

        void Tryif_OnReceiveData(IFServerDLL.DB.MyDBData obj)
        {
            var tradeOnHand = _TradeOnHand.Where(p => p.Instrument == obj.Instrument).FirstOrDefault();
            if (tradeOnHand != null)
            {
                tradeOnHand.UpdateMarketData(obj);
                if (TradeChanged != null)
                {
                    TradeChanged();
                }
                _Account.UpdateMarketProfit(this);
            }
        }
        
        private AccountDemo _Account;
        public AccountDemo Account
        {
            get { return _Account; }
        }
        private List<OrderBase> _OrderHistory;
        public List<OrderBase> OrderHistory
        {
            get { return _OrderHistory; }
        }
        private List<OrderBase> _OrderOnhand;
        public List<OrderBase> OrderOnhand
        {
            get { return _OrderOnhand; }
        }
        private List<TradeBase> _TradeHistory;
        public List<TradeBase> TradeHistory
        {
            get { return _TradeHistory; }
        }
        private List<TradeOnHand> _TradeOnHand;
        public List<TradeOnHand> TradeOnHand
        {
            get { return _TradeOnHand; }
        }
        private List<TradeGroupBase> _TradeGroup;
        public List<TradeGroupBase> TradeGroup
        {
            get { return _TradeGroup; }
        }
        private void AddTrade(TradeBase trade)
        {
            _TradeHistory.Add(trade);
            if (trade.ALLVolumne > 0)
            {
                var onhand = _TradeOnHand.Where(p => p.Instrument == trade.Instrument && p.BuyOrSell == trade.BuyOrSell).FirstOrDefault();
                if (onhand == null)
                {
                    onhand = new TradeOnHand(trade);
                    _TradeOnHand.Add(onhand);
                }
                else
                {
                    onhand.UpdateTrade(trade);
                }
            }
            else
            {
                var onhand = _TradeOnHand.Where(p => p.Instrument == trade.Instrument && p.BuyOrSell != trade.BuyOrSell).FirstOrDefault();
                if (onhand == null)
                {
                    _tryif.AddMessage(new MessageBase("trade onhand unclose"));
                    return;
                }
                onhand.UpdateTrade(trade);
                if (onhand.SumALLVolume == 0)
                {
                    var tradeGroup = _TradeGroup.Where(p => p.Instrument == trade.Instrument && p.BuyOrSell == onhand.BuyOrSell).FirstOrDefault();
                    if (tradeGroup == null)
                    {
                        tradeGroup = new TradeGroupBase(onhand);
                        _TradeGroup.Add(tradeGroup);
                    }
                    else
                    {
                        tradeGroup.AddTradeOnhand(onhand);
                    }
                    _TradeOnHand.Remove(onhand);
                }
            }

           
        }
        private void AddOrder(OrderBase order)
        {
            var ord = _OrderHistory.Where(p => p.OrdID == order.OrdID).FirstOrDefault();
            if (ord == null)
            {
                _OrderHistory.Add(order);
                if (order.IsOnhand())//有效的order
                {
                    var onhand = _OrderOnhand.Where(p => p.OrdID == order.OrdID).FirstOrDefault();
                    if (onhand == null)
                    {
                        _OrderOnhand.Add(order);
                    }
                    else
                    {
                        _OrderOnhand.Remove(onhand);
                        _OrderOnhand.Add(order);
                    }
                }
            }
            else
            {
                if (ord.SeqNo < order.SeqNo)
                {
                    GlobalStatic.Copy(order, ord);
                    var onhand = _OrderOnhand.Where(p => p.OrdID == order.OrdID).FirstOrDefault();
                    if (onhand != null)
                    {
                        GlobalStatic.Copy(order, onhand);
                        if (order.IsOnhand() == false)
                        {
                            _OrderOnhand.Remove(onhand);
                        }
                    }
                }

            }

            

            if (OrderChanged != null)
            {
                OrderChanged();
            }
        }
        public void OnGetOrder(OrderBase order)
        {
            AddOrder(order);
            _Account.UpdateAll(this);
        }

        public void OnGetTrade(TradeBase trade)
        {
            var order = _OrderHistory.Where(p => p.OrdID == trade.OrderID&&p.IsOnhand()&&p.SeqNo<trade.OrdSeqNo).FirstOrDefault();
            if (order != null)
            {

                order.UpdateTrade(trade.ALLVolumne,trade.TradeTime);

                var onhand = _OrderOnhand.Where(p => p.OrdID == order.OrdID).FirstOrDefault();
                if (onhand != null)
                {
                    GlobalStatic.Copy(order, onhand);
                    if (order.IsOnhand() == false)
                    {
                        _OrderOnhand.Remove(onhand);
                    }
                }
                if (OrderChanged != null)
                {
                    OrderChanged();
                }

            }
            
            AddTrade(trade);
            _Account.UpdateAll(this);
            if (TradeChanged != null)
            {
                TradeChanged();
            }

        }


        

        public event Action OrderChanged;

        public event Action TradeChanged;




        
    }
}
